
// 参考: https://nettee.github.io/posts/2018/Understanding-lvalues-and-rvalues-in-C-and-C/

#include <iostream>
#include <utility>

using namespace std;

class Intvec
{
public:
    explicit Intvec(size_t num = 0)
        : m_size(num), m_data(new int[m_size])
    {
        log("constructor");
    }

    ~Intvec()
    {
        log("destructor");
        if (m_data) {
            delete[] m_data;
            m_data = 0;
        }
    }

    Intvec(const Intvec& other)
        : m_size(other.m_size), m_data(new int[m_size])
    {
        log("copy constructor");
        for (size_t i = 0; i < m_size; ++i)
            m_data[i] = other.m_data[i];
    }

    Intvec& operator=(const Intvec& other)
    {
        log("copy assignment operator");
        Intvec tmp(other);
        std::swap(m_size, tmp.m_size);
        std::swap(m_data, tmp.m_data);
        return *this;
    }

	// 这里的 && 代表了右值引用
	// 顾名思义，右值引用可以让我们创建对右值的引用。而且在调用结束后，右值引用就会被销毁。
	Intvec& operator=(Intvec&& other)
	{
		log("move assignment operator");
		std::swap(m_size, other.m_size);
		std::swap(m_data, other.m_data);
		return *this;
	}

private:
    void log(const char* msg)
    {
        cout << "[" << this << "] " << msg << "\n";
    }

    size_t m_size;
    int* m_data;
};

int main() {
	Intvec v1(20);
	Intvec v2;

	cout << "assigning lvalue...\n";
	// v2 = v1;			// 编译器自动识别"="深度拷贝函数
	// v2 = Intvec(33);	// 编译器自动识别到 右值引用函数；如果其未实现，还是使用“=”深度拷贝函数
	cout << "ended assigning lvalue...\n";

}